<template>
  <div class="form-wrapper-zoom-wrapper"
       ref="formWrapperZoomWrapper"
       :form-name-space="context && context.formNameSpace"
       :style="formZoomWrapperStyle">
    <div class="form-wrapper" :style="formWrapperStyle" ref="formWrapper">
      <!--      {{ formZoom.message }}-->
      <!--      {{formZoomWrapperStyle}}-->
      <render/>
    </div>
    <RelationFormModelPop
        :relationData="relationFormModelData"
        v-if="mountRelationFormModelPop"
        v-model:show="showRelationFormModelPop"/>
  </div>
</template>
<script setup>
import {createProps} from '@/utils';
import {computed, nextTick, ref, shallowRef, watch} from 'vue';
import FormEngineUtils from '@comp/FormEngine/FormEngineUtils';
import FormEngineRender from '@comp/FormEngine/FormEngineRender';
import {getAction} from '@/request';
import RelationFormModelPop
  from '@comp/FormEngine/field/relation/RelationFormList/RelationFormModelPop/RelationFormModelPop.vue';
import useFormZoom from '@comp/FormEngine/FormZoom/useFormZoom';


defineOptions({name: 'FormEngine'});
const props = defineProps({
  formDefinition: createProps(Object, () => undefined),
  modelValue: createProps(Object, () => undefined),
  action: createProps(String, undefined),
  view: createProps(String, undefined),
  forceDetail: createProps(Boolean),
});
const emits = defineEmits(['update:modelValue', 'inited']);
const context = ref(undefined);
const formWrapperZoomWrapper = shallowRef();
const formWrapper = shallowRef();
const showRelationFormModelPop = shallowRef(false);
const mountRelationFormModelPop = shallowRef(false);
const manualAuth = ref({});
const relationFormModelData = ref();
const formZoom = useFormZoom({formWrapper, formWrapperZoomWrapper, context});

function openRelationFormModelPop(data) {
  relationFormModelData.value = data;
  mountRelationFormModelPop.value = true;
  setTimeout(() => {
    showRelationFormModelPop.value = true;
  }, 100);
}

watch(() => [showRelationFormModelPop.value], () => {
  nextTick(() => {
    if (!showRelationFormModelPop.value) {
      closedRelationFormModelPop();
    }
  });
}, {
  immediate: false,
});

const formZoomWrapperStyle = computed(() => {
  return {
    // border: '1px solid red',
    overflow: 'hidden',
    ...formZoom.getFormWrapperZoomWrapperStyle.value,
  };
});
const formWrapperStyle = computed(() => {
  try {
    return {
      ...context.value.getFormWrapperStyle(),
      ...formZoom.getFormWrapperStyle.value,
    };
  } catch (e) {
  }
});

function closedRelationFormModelPop() {
  setTimeout(() => {
    mountRelationFormModelPop.value = false;
  }, 500);
}

function render() {
  return checkPropsValues() ? renderForm() : undefined;
}

function renderForm() {
  if (!check()) return undefined;
  context.value = getOrCreateContext();
  return FormEngineRender.render(context.value);
}

function check() {
  if (!props.formDefinition || !props.action || !props.view) return false;
  return true;
}

function createContext() {
  nextTick(() => {
    formZoom.initZoom();
  });
  return FormEngineUtils.createContext({
    props, emits, manualAuth,
    formWrapper,
    openRelationFormModelPop
  });
}

function getOrCreateContext() {
  if (!context.value) return createContext();

  context.value.viewId = props.view;
  context.value.actionId = props.action;
  return context.value;
}

function checkPropsValues() {
  return props.formDefinition && props.action && props.view && props.modelValue;
}

function initFormData(callback) {
  context?.value?.initFormData(callback);
}

watch(() => [props.modelValue, props.formDefinition, props.action, props.view, props.forceDetail], () => {
  if (!props.formDefinition) return;
  nextTick(() => {
    context.value = getOrCreateContext();
    context.value.initIfNecessary();
    context.value.formModel = props.modelValue;
    if (!props.modelValue) {
      initFormData(() => {
        context.value.formFieldUpdate();

        nextTick(() => {
          formZoom.initZoom();
        });
      });
    } else {
      nextTick(() => {
        formZoom.initZoom();
      });
    }
  });
}, {
  immediate: true,
});

watch(() => props.formDefinition, () => {
  nextTick(() => {
    loadManualAuth();
  });
}, {
  immediate: true,
});

function loadManualAuth() {
  if (!props.formDefinition || !props.formDefinition.id) return;
  getAction('/form/loadManualAuth', {formDefinitionId: props.formDefinition.id}).then(data => {
    if (data.success) {
      manualAuth.value = data.result || {};
    }
  });
}

function checkFormData() {
  return context.value.checkFormData()
}

defineExpose({
  initFormData,
  checkFormData
});
</script>
<style lang="less">
@import "style";
</style>
